package site.wtcc.originalfavor.func.aop;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.util.NestedServletException;
import site.wtcc.originalfavor.biz.Result;
import site.wtcc.originalfavor.func.exception.ResponseCode;
import site.wtcc.originalfavor.func.exception.RestException;
import site.wtcc.originalfavor.func.utils.RequestIdUtils;

/**
 * 我的全局异常处理程序
 * 常见编译时异常：IOException下FileNotFoundException，ReflectiveOperationException下NoSuchFieldException、NoSuchMethodException、ClassNotFoundException
 * SQLException，TimeoutException
 * @author hexiaodou
 * @date 2022/09/08 09:38:51
 */
@Slf4j
@RestControllerAdvice
public class MyGlobalExceptionHandler {

    /**
     * 算术异常 整数除以0
     *
     * @param e e
     * @return {@link Result}<{@link T}>
     */
    @ExceptionHandler({ArithmeticException.class})
    public <T> Result<T> arithmeticException(ArithmeticException e) {
        log.error(RequestIdUtils.get() + ",ArithmeticException:", e);
        return Result.ofError("算数异常：" + e);
    }

    @ExceptionHandler({IndexOutOfBoundsException.class})
    public <T> Result<T> indexOutOfBoundsException(IndexOutOfBoundsException e) {
        log.error(RequestIdUtils.get() + ",IndexOutOfBoundsException:", e);
        return Result.ofError("数组越界异常：" + e);
    }

    @ExceptionHandler({ClassCastException.class})
    public <T> Result<T> classCastException(ClassCastException e) {
        log.error(RequestIdUtils.get() + ",ClassCastException:", e);
        return Result.ofError("对象强制转换异常：" + e);
    }

    @ExceptionHandler({NullPointerException.class})
    public <T> Result<T> nullPointerException(NullPointerException e) {
        log.error(RequestIdUtils.get() + ",NullPointerException:", e);
        return Result.ofError("null 异常：" + e);
    }

    @ExceptionHandler({NumberFormatException.class})
    public <T> Result<T> numberFormatException(NumberFormatException e) {
        log.error(RequestIdUtils.get() + ",NumberFormatException:", e);
        return Result.ofError("数值类型转换异常：" + e);
    }

    @ExceptionHandler({IllegalArgumentException.class})
    public <T> Result<T> illegalArgumentException(IllegalArgumentException e) {
        log.error(RequestIdUtils.get() + ",IllegalArgumentException:", e);
        return Result.ofError("不合法或不正确的参数异常：" + e);
    }

    @ExceptionHandler(Exception.class)
    public <T> Result<T> handle(Exception e) {
        log.error(RequestIdUtils.get() + ",Handle exception", e);
        if (e instanceof RestException) {
            RestException restException = (RestException) e;
            log.error("自定义异常：" + restException);
            return Result.ofError(restException.getResponseCode());
        } else if (e instanceof NestedServletException) {
            return Result.ofError(ResponseCode.SYSTEM_ERROR);
        } else {
            return Result.ofError(ResponseCode.SYSTEM_ERROR);
        }
    }
}
